package org.cybzacg.convert.factory;


import lombok.extern.slf4j.Slf4j;
import org.cybzacg.convert.context.ConversionContext;
import org.cybzacg.convert.enums.ConversionStrategyEnum;
import org.cybzacg.convert.strategy.ConversionStrategy;
import org.cybzacg.convert.strategy.impl.LenientConversionStrategy;
import org.cybzacg.convert.strategy.impl.SafeConversionStrategy;
import org.cybzacg.convert.strategy.impl.StrictConversionStrategy;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 转换策略工厂
 * 负责创建和管理转换策略实例
 *
 * @author cybzacg.blog
 * @version 3.0
 * @since 3.0
 */
@Slf4j
public class ConversionStrategyFactory {

    /**
     * 策略实例缓存
     */
    private static final Map<ConversionStrategyEnum, ConversionStrategy> STRATEGY_CACHE = new ConcurrentHashMap<>();

    /**
     * 默认策略
     */
    private static final ConversionStrategyEnum DEFAULT_STRATEGY = ConversionStrategyEnum.SAFE;

    static {
        // 初始化策略实例
        initializeStrategies();
    }

    /**
     * 根据枚举获取策略实例
     *
     * @param strategy 策略枚举
     * @return 策略实例
     */
    public static ConversionStrategy getStrategy(ConversionStrategyEnum strategy) {
        if (strategy == null) {
            strategy = DEFAULT_STRATEGY;
            log.debug("策略为null，使用默认策略: {}", strategy);
        }

        ConversionStrategy strategyInstance = STRATEGY_CACHE.get(strategy);
        if (strategyInstance == null) {
            log.warn("未找到策略实例: {}，使用默认策略", strategy);
            strategyInstance = STRATEGY_CACHE.get(DEFAULT_STRATEGY);
        }

        return strategyInstance;
    }

    /**
     * 根据上下文获取策略实例
     *
     * @param context 转换上下文
     * @return 策略实例
     */
    public static ConversionStrategy getStrategy(ConversionContext context) {
        if (context == null) {
            log.debug("上下文为null，使用默认策略: {}", DEFAULT_STRATEGY);
            return getStrategy(DEFAULT_STRATEGY);
        }

        ConversionStrategyEnum strategy = context.getStrategy();
        return getStrategy(strategy);
    }

    /**
     * 根据策略名称获取策略实例
     *
     * @param strategyName 策略名称
     * @return 策略实例
     */
    public static ConversionStrategy getStrategy(String strategyName) {
        if (strategyName == null || strategyName.trim().isEmpty()) {
            log.debug("策略名称为空，使用默认策略: {}", DEFAULT_STRATEGY);
            return getStrategy(DEFAULT_STRATEGY);
        }

        try {
            ConversionStrategyEnum strategy = ConversionStrategyEnum.fromCode(strategyName);
            return getStrategy(strategy);
        } catch (Exception e) {
            log.warn("无效的策略名称: {}，使用默认策略: {}", strategyName, DEFAULT_STRATEGY);
            return getStrategy(DEFAULT_STRATEGY);
        }
    }

    /**
     * 注册自定义策略
     *
     * @param strategy 策略枚举
     * @param strategyInstance 策略实例
     */
    public static void registerStrategy(ConversionStrategyEnum strategy, ConversionStrategy strategyInstance) {
        if (strategy == null || strategyInstance == null) {
            log.warn("策略或策略实例为null，忽略注册");
            return;
        }

        STRATEGY_CACHE.put(strategy, strategyInstance);
        log.info("注册自定义策略: {} -> {}", strategy, strategyInstance.getClass().getSimpleName());
    }

    /**
     * 移除策略
     *
     * @param strategy 策略枚举
     * @return 是否成功移除
     */
    public static boolean removeStrategy(ConversionStrategyEnum strategy) {
        if (strategy == null) {
            return false;
        }

        // 不允许移除默认策略
        if (strategy == DEFAULT_STRATEGY) {
            log.warn("不允许移除默认策略: {}", strategy);
            return false;
        }

        ConversionStrategy removed = STRATEGY_CACHE.remove(strategy);
        if (removed != null) {
            log.info("移除策略: {} -> {}", strategy, removed.getClass().getSimpleName());
            return true;
        }

        return false;
    }

    /**
     * 检查策略是否存在
     *
     * @param strategy 策略枚举
     * @return 是否存在
     */
    public static boolean hasStrategy(ConversionStrategyEnum strategy) {
        return strategy != null && STRATEGY_CACHE.containsKey(strategy);
    }

    /**
     * 获取所有可用的策略
     *
     * @return 策略枚举数组
     */
    public static ConversionStrategyEnum[] getAvailableStrategies() {
        return STRATEGY_CACHE.keySet().toArray(new ConversionStrategyEnum[0]);
    }

    /**
     * 获取策略统计信息
     *
     * @return 统计信息
     */
    public static StrategyStatistics getStatistics() {
        return new StrategyStatistics(
            STRATEGY_CACHE.size(),
            DEFAULT_STRATEGY,
            STRATEGY_CACHE.keySet().toArray(new ConversionStrategyEnum[0])
        );
    }

    /**
     * 清理所有自定义策略（保留内置策略）
     */
    public static void clearCustomStrategies() {
        log.info("清理自定义策略");

        // 保留内置策略
        Map<ConversionStrategyEnum, ConversionStrategy> builtinStrategies = new ConcurrentHashMap<>();
        builtinStrategies.put(ConversionStrategyEnum.STRICT, STRATEGY_CACHE.get(ConversionStrategyEnum.STRICT));
        builtinStrategies.put(ConversionStrategyEnum.LENIENT, STRATEGY_CACHE.get(ConversionStrategyEnum.LENIENT));
        builtinStrategies.put(ConversionStrategyEnum.SAFE, STRATEGY_CACHE.get(ConversionStrategyEnum.SAFE));

        STRATEGY_CACHE.clear();
        STRATEGY_CACHE.putAll(builtinStrategies);

        log.info("自定义策略清理完成，保留内置策略数量: {}", STRATEGY_CACHE.size());
    }

    /**
     * 重置工厂到初始状态
     */
    public static void reset() {
        log.info("重置策略工厂");
        STRATEGY_CACHE.clear();
        initializeStrategies();
    }

    /**
     * 初始化内置策略
     */
    private static void initializeStrategies() {
        log.debug("初始化内置转换策略");

        try {
            // 注册严格策略
            STRATEGY_CACHE.put(ConversionStrategyEnum.STRICT, new StrictConversionStrategy());
            log.debug("注册严格策略: {}", ConversionStrategyEnum.STRICT);

            // 注册宽松策略
            STRATEGY_CACHE.put(ConversionStrategyEnum.LENIENT, new LenientConversionStrategy());
            log.debug("注册宽松策略: {}", ConversionStrategyEnum.LENIENT);

            // 注册安全策略
            STRATEGY_CACHE.put(ConversionStrategyEnum.SAFE, new SafeConversionStrategy());
            log.debug("注册安全策略: {}", ConversionStrategyEnum.SAFE);

            log.info("内置转换策略初始化完成，共{}个策略", STRATEGY_CACHE.size());

        } catch (Exception e) {
            log.error("初始化内置策略失败", e);
            throw new RuntimeException("策略工厂初始化失败", e);
        }
    }

    /**
     * 策略统计信息
     */
    public static class StrategyStatistics {
        private final int totalStrategies;
        private final ConversionStrategyEnum defaultStrategy;
        private final ConversionStrategyEnum[] availableStrategies;

        public StrategyStatistics(int totalStrategies, ConversionStrategyEnum defaultStrategy,
                                ConversionStrategyEnum[] availableStrategies) {
            this.totalStrategies = totalStrategies;
            this.defaultStrategy = defaultStrategy;
            this.availableStrategies = availableStrategies;
        }

        public int getTotalStrategies() {
            return totalStrategies;
        }

        public ConversionStrategyEnum getDefaultStrategy() {
            return defaultStrategy;
        }

        public ConversionStrategyEnum[] getAvailableStrategies() {
            return availableStrategies;
        }

        @Override
        public String toString() {
            return String.format("StrategyStatistics{总数=%d, 默认策略=%s, 可用策略=%s}",
                               totalStrategies, defaultStrategy,
                               java.util.Arrays.toString(availableStrategies));
        }
    }
}
